package com.xyht.sca_s.student_manage_system.scheduling;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xyht.sca_s.student_manage_system.auth.util.JwtTokenUtil;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.mapper.RxAdvanceRegistrationStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.SmsCarUseApplication;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.entity.SmsCarWarehousing;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.mapper.SmsCarUseApplicationMapper;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.mapper.SmsCarWarehousingMapper;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.service.SmsCarUseApplicationService;
import com.xyht.sca_s.student_manage_system.modules.carUseManage.service.SmsCarWarehousingService;
import com.xyht.sca_s.student_manage_system.modules.chargePayment.entity.SmsWnsChargePaymentCategoryDivide;
import com.xyht.sca_s.student_manage_system.modules.chargePayment.entity.SmsWnsChargePaymentRecord;
import com.xyht.sca_s.student_manage_system.modules.chargePayment.mapper.SmsWnsChargePaymentRecordMapper;
import com.xyht.sca_s.student_manage_system.modules.clockIn.entity.SmsClockIn;
import com.xyht.sca_s.student_manage_system.modules.clockIn.entity.SmsClockInClassesSetting;
import com.xyht.sca_s.student_manage_system.modules.clockIn.entity.SmsClockInGroupSetting;
import com.xyht.sca_s.student_manage_system.modules.clockIn.entity.SmsClockInGroupUserRelation;
import com.xyht.sca_s.student_manage_system.modules.clockIn.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.clockIn.mapper.SmsClockInMapper;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.RxRegistrationChargePaymentCategoryDivide;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.RxRegistrationChargePaymentRecord;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.mapper.RxRegistrationChargePaymentCategoryDivideMapper;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.mapper.RxRegistrationChargePaymentRecordMapper;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.carUseReturn.constant.carStatusConstant.CAR_STATUS_OVERTIME;
import static com.xyht.sca_s.student_manage_system.modules.chargePayment.constant.SmsWnsChargePaymentRecordConstant.CHARGE_PAYMENT_RECORD_NEW_STU_PREPAY;
import static com.xyht.sca_s.student_manage_system.modules.clockIn.constant.ClockInObjectTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.clockIn.constant.ClockInStateConstant.CLOCK_IN_STATE_LACK;
import static com.xyht.sca_s.student_manage_system.modules.clockIn.constant.ClockInTypeConstant.CLOCK_IN_TYPE_END;
import static com.xyht.sca_s.student_manage_system.modules.clockIn.constant.ClockInTypeConstant.CLOCK_IN_TYPE_START;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum.TIPS_TYPE_ENUM_MESSAGE;

@Component
@Log4j2
public class OrderStatusSchedulingTask {
    //++++++++++++++++++++++++++++++++++++++++++邓翔内+++++++++++++++++++++++++++++++++++++++++
    /**
     * @Autowired 对象定义、组件引用
     */
    //++++++++++++++++++++++++++++++++++++++++++杨航+++++++++++++++++++++++++++++++++++++++++
    @Autowired
    private SmsCarUseApplicationMapper smsCarUseApplicationMapper;
    @Autowired
    private SmsCarWarehousingMapper smsCarWarehousingMapper;
    @Autowired
    private SmsCarUseApplicationService smsCarUseApplicationService;
    @Autowired
    private SmsCarWarehousingService smsCarWarehousingService;

    //++++++++++++++++++++++++++++++++++++++++++张川+++++++++++++++++++++++++++++++++++++++++
    @Autowired
    private SmsClockInMapper clockInMapper;
    @Autowired
    private SmsClockInGroupSettingMapper groupSettingMapper;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private SmsClockInClassesSettingMapper classesSettingMapper;
    @Autowired
    private NewTipsUtil newTipsUtil;
    @Autowired
    private SmsClockInGroupUserRelationMapper groupUserRelationMapper;
    @Resource
    private SmsWnsChargePaymentRecordMapper smsWnsChargePaymentRecordMapper;
    @Resource
    private RxAdvanceRegistrationStudentInfoMapper rxAdvanceRegistrationStudentInfoMapper;
    @Resource
    private RxRegistrationChargePaymentRecordMapper chargePaymentRecordMapper;
    @Resource
    private RxRegistrationChargePaymentCategoryDivideMapper chargePaymentCategoryDivideMapper;

    //++++++++++++++++++++++++++++++++++++++++++许正+++++++++++++++++++++++++++++++++++++++++


    @Resource
    PlatformTransactionManager transactionManager;

//    @Scheduled(cron = "0 */1 * * * ?")//每隔 1 分钟执行一次
    public void schedulingTask() {

        //++++++++++++++++++++++++++++++++++++++++++邓翔内+++++++++++++++++++++++++++++++++++++++++
        log.debug("test1()++++++++++++++++++++++++++++开始计时");
        test1();
        log.debug("test1()++++++++++++++++++++++++++++结束计时");

        //++++++++++++++++++++++++++++++++++++++++++杨航+++++++++++++++++++++++++++++++++++++++++
        log.debug("test2()++++++++++++++++++++++++++++开始计时");
        test2();
        log.debug("test2()++++++++++++++++++++++++++++结束计时");


        //++++++++++++++++++++++++++++++++++++++++++张川+++++++++++++++++++++++++++++++++++++++++
        /**
         * 定时考勤人为打卡时,系统自动打异常卡
         */
        log.debug("test3()++++++++++++++++++++++++++++开始计时");
        test3();
        log.debug("test3()++++++++++++++++++++++++++++结束计时");
        test5();
        //++++++++++++++++++++++++++++++++++++++++++许正+++++++++++++++++++++++++++++++++++++++++

        test4();


    }

    //++++++++++++++++++++++++++++++++++++++++++邓翔内+++++++++++++++++++++++++++++++++++++++++

    /**
     * 需要定时查询的逻辑
     */
    public void test1() {
//        //开启事务
//        DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
//        // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
//        dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
//        // 设置嵌套事务
//        TransactionStatus status = transactionManager.getTransaction(dt);
//
//
//
//
//
//
//
//        // 手动回滚事务
//        transactionManager.rollback(status);
//
//        transactionManager.commit(status);
//        if (status.isNewTransaction() && !status.isCompleted()) {
//            transactionManager.commit(status);
//            log.debug("++++++进来了");
//        }
        log.debug("++++++++++++++++++++++++++测试");
    }


    //++++++++++++++++++++++++++++++++++++++++++杨航+++++++++++++++++++++++++++++++++++++++++

    /**
     *
     */
    public void test2() {
        DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
        // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
        dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 设置嵌套事务
        TransactionStatus status = transactionManager.getTransaction(dt);

        //系统当前时间
        try {
            QueryWrapper<SmsCarUseApplication> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SmsCarUseApplication::getIsUse, 0)
                    .eq(SmsCarUseApplication::getAllowStatus, 1);
            List<SmsCarUseApplication> list = smsCarUseApplicationMapper.selectList(queryWrapper);
            List<SmsCarUseApplication> smsCarUseApplicationList = new ArrayList<>();
            List<SmsCarWarehousing> smsCarWarehousingList = new ArrayList<>();
            for (SmsCarUseApplication application : list) {
                Date date = new Date();
                SmsCarWarehousing warehousing = smsCarWarehousingMapper.selectById(application.getCarId());
                if (date.compareTo(application.getUseStartTime()) >= 0 && date.compareTo(application.getUseEndTime()) <= 0) {
                    if (isNullOrEmpty(warehousing)) {
                        continue;
                    }
                    SmsCarWarehousing smsCarWarehousing = new SmsCarWarehousing();
                    smsCarWarehousing.setId(warehousing.getId());
                    smsCarWarehousing.setCarStatus(2);
                    smsCarWarehousingList.add(smsCarWarehousing);
                    SmsCarUseApplication smsCarUseApplication = new SmsCarUseApplication();
                    smsCarUseApplication.setId(application.getId());
                    smsCarUseApplication.setIsReturn(0);
                    smsCarUseApplication.setIsUse(1);
                    smsCarUseApplicationList.add(smsCarUseApplication);
                }

            }
            smsCarUseApplicationService.updateBatchById(smsCarUseApplicationList);

            Date date = new Date();
            QueryWrapper<SmsCarUseApplication> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(SmsCarUseApplication::getIsUse, 1)
                    .eq(SmsCarUseApplication::getIsReturn, 0)
                    .le(SmsCarUseApplication::getUseEndTime, date);
            List<SmsCarUseApplication> list1 = smsCarUseApplicationMapper.selectList(queryWrapper1);
            List<String> carIDList = list1.stream().map(SmsCarUseApplication::getCarId).collect(Collectors.toList());
            QueryWrapper<SmsCarWarehousing> queryWrapper2 = new QueryWrapper<SmsCarWarehousing>();
            if (carIDList.size()>0){
                queryWrapper2.lambda()
                        .in(SmsCarWarehousing::getId, carIDList);
            }
            queryWrapper2.lambda()
                    .ne(SmsCarWarehousing::getCarStatus, CAR_STATUS_OVERTIME);
            List<SmsCarWarehousing> carList = smsCarWarehousingMapper.selectList(queryWrapper2);
            if (carList != null && carList.size() > 0) {
                for (SmsCarWarehousing application : carList) {
                    SmsCarWarehousing smsCarWarehousing = new SmsCarWarehousing();
                    smsCarWarehousing.setId(application.getId());
                    smsCarWarehousing.setCarStatus(CAR_STATUS_OVERTIME);
                    smsCarWarehousingList.add(smsCarWarehousing);
                }
                smsCarWarehousingService.updateBatchById(smsCarWarehousingList);
            }

            transactionManager.commit(status);
        } catch (Exception e) {
            e.printStackTrace();
            // 手动回滚事务
            transactionManager.rollback(status);
        } finally {
            if (status.isNewTransaction() && !status.isCompleted()) {
                transactionManager.commit(status);
                log.debug("++++++进来了");
            }
        }

    }

    //++++++++++++++++++++++++++++++++++++++++++张川+++++++++++++++++++++++++++++++++++++++++

    /**
     *
     */
    public void test3() {
        String OSName = System.getProperty("os.name");
        boolean result = OSName.toLowerCase().startsWith("win");
        if (!result) {
            //查看最新的考勤组
            log.info("考勤组定时进来了......");
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            try {
                List<SmsClockInGroupSetting> groupSettings = groupSettingMapper.selectList(null);
                if (groupSettings == null || groupSettings.size() < 1) {
                    transactionManager.commit(status);
                    return;
                }
                for (SmsClockInGroupSetting groupSetting : groupSettings) {
                    List<String> list = groupUserRelationMapper.selectList(new LambdaQueryWrapper<SmsClockInGroupUserRelation>()
                                    .eq(SmsClockInGroupUserRelation::getClockInGroupId, groupSetting.getId())).stream()
                            .map(SmsClockInGroupUserRelation::getUserId).collect(Collectors.toList());
                    if (list.size() < 1) {
                        continue;
                    }
                    List<String> userList = new ArrayList<>();
                    userList = list;
                    //校验选取角色时
                    Date date = new Date();
                    String clockInfoKey = TimeUtil.DateSimpleformat(date) + "-";
                    //查询当天的班次信息
                    SmsClockInClassesSetting classesSetting = classesSettingMapper.selectOne(new LambdaQueryWrapper<SmsClockInClassesSetting>()
                            .eq(SmsClockInClassesSetting::getClockInGroupId, groupSetting.getId())
                            .eq(SmsClockInClassesSetting::getWeekday, date.getDay()));
                    if (classesSetting != null) {
                        //格式转化
                        Date startHours = classesSetting.getStartHours();
                        Date endHours = classesSetting.getEndHours();
                        startHours.setYear(date.getYear());
                        startHours.setMonth(date.getMonth());
                        startHours.setDate(date.getDate());
                        endHours.setYear(date.getYear());
                        endHours.setMonth(date.getMonth());
                        endHours.setDate(date.getDate());
                        //上班缺卡限制
                        Integer startLackTimeLimit = classesSetting.getStartLackTimeLimit();
                        Date lackTime = TimeUtil.AddMinute(startHours, startLackTimeLimit);
                        //下班最晚限制
                        Integer latestTimeLimit = classesSetting.getLatestTimeLimit();
                        Date latestTime = TimeUtil.AddMinute(endHours, latestTimeLimit);
                        for (String userId : userList) {
                            //上班
                            String startKey = clockInfoKey + userId + "-" + CLOCK_IN_TYPE_START;
                            String startValue = cacheUtil.getObject(startKey, String.class);
                            if (startValue == null || !startValue.equals("flag")) {
                                if (date.getTime() > lackTime.getTime()) {
                                    SmsClockIn clockIn = new SmsClockIn();
                                    clockIn.setUserId(userId);
                                    clockIn.setClockInState(CLOCK_IN_STATE_LACK);
                                    clockIn.setClockInDate(date);
                                    clockIn.setClockInType(CLOCK_IN_TYPE_START);
                                    clockIn.setClockInGroupId(groupSetting.getId());
                                    clockIn.setClassesId(classesSetting.getId());
                                    clockInMapper.insert(clockIn);
                                    cacheUtil.add(startKey, "flag");
                                }

                            }
                            //下班
                            String endKey = clockInfoKey + userId + "-" + CLOCK_IN_TYPE_END;
                            String endValue = cacheUtil.getObject(endKey, String.class);
                            if (endValue == null || !endValue.equals("flag")) {
                                if (date.getTime() > latestTime.getTime()) {
                                    SmsClockIn clockIn = new SmsClockIn();
                                    clockIn.setUserId(userId);
                                    clockIn.setClockInState(CLOCK_IN_STATE_LACK);
                                    clockIn.setClockInDate(date);
                                    clockIn.setClockInType(CLOCK_IN_TYPE_END);
                                    clockIn.setClockInGroupId(groupSetting.getId());
                                    clockIn.setClassesId(classesSetting.getId());
                                    clockInMapper.insert(clockIn);
                                    cacheUtil.add(endKey, "flag");
                                }
                            }
                            //上班消息通知
                            Date remindTime = TimeUtil.AddMinute(startHours, -10);
                            double abs = Math.abs((double) TimeUtil.calculatetimeGapMinute(date, remindTime));
                            if (abs < 1) {
                                //                newTipsUtil.addNewTips(TIPS_TYPE_ENUM_MESSAGE,userId,);
                            }
                            //下班消息通知
                            Date endTime = TimeUtil.AddMinute(endHours, 5);
                            double abs1 = Math.abs((double) TimeUtil.calculatetimeGapMinute(date, endTime));
                            if (abs1 < 1) {
                                //                newTipsUtil.addNewTips(TIPS_TYPE_ENUM_MESSAGE,userId,);
                            }
                        }
                        log.info("考勤组定时结束了......");
                        transactionManager.commit(status);
                    }
                }


            } catch (Exception e) {
                e.printStackTrace();
                // 手动回滚事务
                transactionManager.rollback(status);
            } finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    transactionManager.commit(status);
                }
            }

        }
    }

    //++++++++++++++++++++++++++++++++++++++++++许正+++++++++++++++++++++++++++++++++++++++++

    /**
     *招生管理 预报名支付查询
     */
    @Scheduled(cron = "0 */1 * * * ?")//每隔 1 分钟执行一次
    public void test4() {
        // 移除无效数据(超过半小时未支付)
        List<SmsWnsChargePaymentRecord> ivalidPaymentRecordList = smsWnsChargePaymentRecordMapper.selectList(new LambdaQueryWrapper<SmsWnsChargePaymentRecord>()
                .le(SmsWnsChargePaymentRecord::getExpireTime, new Date())
                .eq(SmsWnsChargePaymentRecord::getType,CHARGE_PAYMENT_RECORD_NEW_STU_PREPAY)
                .isNull(SmsWnsChargePaymentRecord::getPaymentTime));
        if (!ivalidPaymentRecordList.isEmpty()) {
            //删除预报名学生信息
            List<String> stuIdList = ivalidPaymentRecordList.stream().map(SmsWnsChargePaymentRecord::getEventId).collect(Collectors.toList());
            rxAdvanceRegistrationStudentInfoMapper.deleteBatchIds(stuIdList);
            //删除未缴费记录
            List<String> ivalidPaymentRecordIdList = ivalidPaymentRecordList.stream().map(SmsWnsChargePaymentRecord::getId).distinct().collect(Collectors.toList());
            smsWnsChargePaymentRecordMapper.deleteBatchIds(ivalidPaymentRecordIdList);

        }
    }

    /**
     *招生管理三个应用
     */
    @Scheduled(cron = "0 */1 * * * ?")//每隔 1 分钟执行一次
    public void test5() {
        // 移除无效数据(超过半小时未支付)
        List<RxRegistrationChargePaymentRecord> invalidPaymentRecordList = chargePaymentRecordMapper.selectList(new LambdaQueryWrapper<RxRegistrationChargePaymentRecord>()
                .le(RxRegistrationChargePaymentRecord::getExpireTime, new Date())
                .isNull(RxRegistrationChargePaymentRecord::getPaymentTime));
        if (!invalidPaymentRecordList.isEmpty()) {
            List<String> invalidPaymentRecordIdList = invalidPaymentRecordList.stream().map(RxRegistrationChargePaymentRecord::getId).distinct().collect(Collectors.toList());
            chargePaymentCategoryDivideMapper.delete(new LambdaQueryWrapper<RxRegistrationChargePaymentCategoryDivide>()
                    .in(RxRegistrationChargePaymentCategoryDivide::getPaymentRecordId, invalidPaymentRecordIdList));
            chargePaymentRecordMapper.deleteBatchIds(invalidPaymentRecordIdList);
        }
    }
}
